package git.soulbgm.job;

import com.dangdang.ddframe.job.lite.internal.storage.JobNodePath;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 操作作业的API
 *
 * @author SoulBGM
 * @date 2020/11/23
 */
@Component
public class JobOperateAPI {

    @Autowired
    private ZookeeperRegistryCenter regCenter;

    /**
     * 作业立刻执行.
     *
     * <p>作业在不与上次运行中作业冲突的情况下才会启动, 并在启动后自动清理此标记.</p>
     *
     * @param jobName  作业名称
     * @param serverIp 作业服务器IP地址
     */
    public void trigger(String jobName, String serverIp) {
        JobNodePath jobNodePath = new JobNodePath(jobName);
        for (String each : regCenter.getChildrenKeys(jobNodePath.getInstancesNodePath())) {
            regCenter.persist(jobNodePath.getInstanceNodePath(each), "TRIGGER");
        }
    }

    /**
     * 作业禁用.
     *
     * <p>会重新分片.</p>
     *
     * @param jobName  作业名称
     * @param serverIp 作业服务器IP地址
     */
    public void disable(String jobName, String serverIp) {
        disableOrEnableJobs(jobName, serverIp, true);
    }

    /**
     * 作业启用.
     *
     * @param jobName  作业名称
     * @param serverIp 作业服务器IP地址
     */
    public void enable(String jobName, String serverIp) {
        disableOrEnableJobs(jobName, serverIp, false);
    }

    /**
     * 禁用或启用作业
     *
     * @param jobName  作业名
     * @param serverIp 服务器ip
     * @param disabled 禁用
     */
    private void disableOrEnableJobs(String jobName, String serverIp, boolean disabled) {
        if (jobName != null && serverIp != null) {
            persistDisabledOrEnabledJob(jobName, serverIp, disabled);
        } else if (jobName != null) {
            JobNodePath jobNodePath = new JobNodePath(jobName);
            for (String each : regCenter.getChildrenKeys(jobNodePath.getServerNodePath())) {
                if (disabled) {
                    regCenter.persist(jobNodePath.getServerNodePath(each), "DISABLED");
                } else {
                    regCenter.persist(jobNodePath.getServerNodePath(each), "");
                }
            }
        } else if (serverIp != null) {
            List<String> jobNames = regCenter.getChildrenKeys("/");
            for (String each : jobNames) {
                if (regCenter.isExisted(new JobNodePath(each).getServerNodePath(serverIp))) {
                    persistDisabledOrEnabledJob(each, serverIp, disabled);
                }
            }
        }
    }

    /**
     * 持久禁用或启用作业
     *
     * @param jobName  作业名
     * @param serverIp 服务器ip
     * @param disabled 禁用
     */
    private void persistDisabledOrEnabledJob(final String jobName, final String serverIp, final boolean disabled) {
        JobNodePath jobNodePath = new JobNodePath(jobName);
        String serverNodePath = jobNodePath.getServerNodePath(serverIp);
        if (disabled) {
            regCenter.persist(serverNodePath, "DISABLED");
        } else {
            regCenter.persist(serverNodePath, "");
        }
    }

    /**
     * 作业关闭.
     *
     * @param jobName  作业名称
     * @param serverIp 作业服务器IP地址
     */
    public void shutdown(String jobName, String serverIp) {
        if (jobName != null && serverIp != null) {
            JobNodePath jobNodePath = new JobNodePath(jobName);
            for (String each : regCenter.getChildrenKeys(jobNodePath.getInstancesNodePath())) {
                if (serverIp.equals(each.split("@-@")[0])) {
                    regCenter.remove(jobNodePath.getInstanceNodePath(each));
                }
            }
        } else if (jobName != null) {
            JobNodePath jobNodePath = new JobNodePath(jobName);
            for (String each : regCenter.getChildrenKeys(jobNodePath.getInstancesNodePath())) {
                regCenter.remove(jobNodePath.getInstanceNodePath(each));
            }
        } else if (serverIp != null) {
            List<String> jobNames = regCenter.getChildrenKeys("/");
            for (String job : jobNames) {
                JobNodePath jobNodePath = new JobNodePath(job);
                List<String> instances = regCenter.getChildrenKeys(jobNodePath.getInstancesNodePath());
                for (String each : instances) {
                    if (serverIp.equals(each.split("@-@")[0])) {
                        regCenter.remove(jobNodePath.getInstanceNodePath(each));
                    }
                }
            }
        }
    }

    /**
     * 作业删除.
     *
     * @param jobName  作业名称
     * @param serverIp 作业服务器IP地址
     */
    public void remove(String jobName, String serverIp) {
        shutdown(jobName, serverIp);
        if (jobName != null && serverIp != null) {
            regCenter.remove(new JobNodePath(jobName).getServerNodePath(serverIp));
        } else if (jobName != null) {
            JobNodePath jobNodePath = new JobNodePath(jobName);
            List<String> servers = regCenter.getChildrenKeys(jobNodePath.getServerNodePath());
            for (String each : servers) {
                regCenter.remove(jobNodePath.getServerNodePath(each));
            }
        } else if (serverIp != null) {
            List<String> jobNames = regCenter.getChildrenKeys("/");
            for (String each : jobNames) {
                regCenter.remove(new JobNodePath(each).getServerNodePath(serverIp));
            }
        }
    }

    /**
     * 删除所有
     *
     * @param jobName 作业名
     */
    @SneakyThrows
    public void removeAll(String jobName) {
        String key = "/" + jobName;
        regCenter.remove(key);
        if (regCenter.isExisted(key)) {
            Thread.sleep(1000);
            regCenter.remove(key);
        }
    }

}
